package com.competition.login.controller;

import com.competition.commonutils.JwtUtils;
import com.competition.login.entity.User;
import com.competition.login.service.UserService;
import com.competition.login.util.ConstantWxUtils;
import com.competition.login.util.HttpClientUtils;
import com.competition.servicebase.exceptionhandler.MyException;
import com.google.gson.Gson;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
//import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.servlet.http.HttpServletRequest;
import java.net.URLEncoder;
import java.util.HashMap;

@CrossOrigin
@Controller  //只是请求地址，不需要返回数据
@RequestMapping("/api/ucenter/wx")
@Api(description = "微信扫码登录")
public class WxApiController {

    @Autowired
    private UserService userService;

    //1 生成微信扫描二维码
    @GetMapping("login")
    @ApiOperation("请求这个地址获取微信二维码")
    public String getWxCode() {
        //固定地址，后面拼接参数
        //String url = "https://open.weixin.qq.com/" +
        //"connect/qrconnect?appid="+ ConstantWxUtils.WX_OPEN_APP_ID+"&response_type=code";
        // 微信开放平台授权baseUrl  %s相当于?代表占位符
        String baseUrl = "https://open.weixin.qq.com/connect/qrconnect" +
                "?appid=%s" +
                "&redirect_uri=%s" +
                "&response_type=code" +
                "&scope=snsapi_login" +
                "&state=%s" +
                "#wechat_redirect";
        //对redirect_url进行URLEncoder编码
        String redirectUrl = ConstantWxUtils.WX_OPEN_REDIRECT_URL;
        try {
            redirectUrl = URLEncoder.encode(redirectUrl, "utf-8");
        } catch (Exception e) {
        }
        //设置%s里面值
        String url = String.format(
                baseUrl,
                ConstantWxUtils.WX_OPEN_APP_ID,
                redirectUrl,
                "atguigu"
        );
        //重定向到请求微信地址里面
        return "redirect:" + url;
    }

    /**
     * @param code
     * @param state
     * @return
     */
    @GetMapping("callback")
    //微信扫码登录，用户不需要手动注册
    @ApiOperation("不用管这个接口")
    public String callback(String code, String state) {
        //1.获取参数code和state
        System.out.println(code);//得到授权临时票据code=>类似于手机验证码
        System.out.println(state);//原样传递，在getWxCode()方法的state中传递得数据
        //2.拿到code值之后，请求微信地址，获取两个值==>access_token:访问凭证；openId:每个微信得唯一标识（返回json字符串，要解析json字符串）
        String baseAccessTokenUrl = "https://api.weixin.qq.com/sns/oauth2/access_token" +
                "?appid=%s" +
                "&secret=%s" +
                "&code=%s" +
                "&grant_type=authorization_code";
        String accessTokenUrl = String.format(baseAccessTokenUrl,//要拼接得字符串
                ConstantWxUtils.WX_OPEN_APP_ID,//微信id
                ConstantWxUtils.WX_OPEN_APP_SECRET,//密钥
                code);//code值
        //从redis中将state获取出来，和当前传入的state作比较
        //如果一致则放行，如果不一致则抛出异常：非法访问
        //向认证服务器发送请求换取access_token
        String result = null;
        try {
            result = HttpClientUtils.get(accessTokenUrl);//使用httpClient模拟浏览器发送请求
        } catch (Exception e) {
            throw new MyException(20001, "获取access_token失败");
        }
        //解析json字符串
        Gson gson = new Gson();
        HashMap map = gson.fromJson(result, HashMap.class);
        String accessToken = (String) map.get("access_token");
        String openid = (String) map.get("openid");
        //3.拿到access_token和openId，再去请求微信提供得一个地址，最终得到微信扫码人得信息（返回json字符串），使用httpClient发送请求
        //（不用浏览器也可以模拟出浏览器得效果）查询数据库当前用用户是否曾经使用过微信登录（如果没有，则要把用户数据加进数据库）
        User member = userService.getOpenIdMember(openid);//查询用户之前是否用过微信登录
        if (member == null) {
            System.out.println("新用户注册");
            //访问微信的资源服务器，获取用户信息
            String baseUserInfoUrl = "https://api.weixin.qq.com/sns/userinfo" +
                    "?access_token=%s" +
                    "&openid=%s";
            String userInfoUrl = String.format(baseUserInfoUrl, accessToken, openid);
            String resultUserInfo = null;
            try {
                resultUserInfo = HttpClientUtils.get(userInfoUrl);
                System.out.println("resultUserInfo==========" + resultUserInfo);
            } catch (Exception e) {
                throw new MyException(20001, "获取用户信息失败");
            }
            //解析json
            HashMap<String, Object> mapUserInfo = gson.fromJson(resultUserInfo, HashMap.class);
            String nickname = (String) mapUserInfo.get("nickname");
            String headimgurl = (String) mapUserInfo.get("headimgurl");
            //向数据库中插入一条记录
            member = new User();
            member.setNickname(nickname);
            member.setOpenid(openid);
            member.setAvatar(headimgurl);
            userService.save(member);
        }
        String token = JwtUtils.getJwtToken(member.getId(), member.getNickname());
        //因为端口号不同存在蛞蝓问题，cookie不能跨域，所以这里使用url重写
        return "redirect:http://localhost:8080/home?token=" + token;
    }
}

